Skip to main content

How to retrieve Office 365 profile pictures with Microsoft Graph in .NET

Small guide on how to pull pictures from Microsoft Graph API

· 3 min read View Comments
Martin Jurran
Software Engineer - OSS, golang, .NET

Inofficial logo of Microsoft Graph

Inofficial logo of Microsoft Graph (Photo by the author)

In some cases, external services need to use employees’ identities - especially profile pictures. There is probably no more central place than Entra ID to acquire profile pictures.

Example: We are setting up an external, premade solution that lacks out-of-the-box integration with identity providers. And along with metadata, we may also want to transfer profile pictures into our solution.

Luckily, most organizations have an identity store that we can utilize. In our case, we can use Office 365 with its Entra ID. With these tools, we can easily access the necessary data to build our feature.

Idea

We want to enhance the quality of data in our external software by importing profile pictures directly from Entra ID. We need to figure out how to upload those raw pictures somewhere or post them to the external software’s API, depending on its design.

This will require us to think about our data transfer and storage solutions, as well as how to interface with different APIs.

Technical Base

Retrieving User Photos with MS Graph API

The first step would be to take a look at the Photo API of Microsoft Graph, to get a rough understanding of the available functionalities. The API is providing the profile pictures stored in Exchange Online / Entra ID.

We have two types of queries:

//Request your own photo

Metadata: https://graph.microsoft.com/1.0/me/photo
Photo: https://graph.microsoft.com/1.0/me/photo/$value
//Request someone else's photo

Metadata: https://graph.microsoft.com/1.0/users/max.mustermann@contoso.com/photo
Photo: https://graph.microsoft.com/1.0/users/max.mustermann@contoso.com/photo/$value

Get profilePhoto — Microsoft Graph v1.0 | Microsoft Learn

Implementation

1. Retrieve User Photos with PowerShell / native-cmdlets

Get-AzureADUserThumbnailPhoto is a cmdlet for pulling data from Entra ID to retrieve a user’s thumbnail photo. It’s the easiest way to utilize above-mentioned API endpoint without implementing anything yourself.

Be aware, that the usage of this cmdlet is most likely to be restricted in almost all organizations and that you need to acquire additional rights in order to execute it.

I would not recommend using that approach in production scenarios if it were avoidable.

Get-AzureADUserThumbnailPhoto -ObjectId "" -FileName ""

Get-AzureADUserThumbnailPhoto (AzureAD) | Microsoft Learn

2. Retrieve User Photos with C#

In order to use Microsoft Graph, we need to implement an authentication flow, just as covered in this article: Establishing OAuth 2.0 Authentication to SharePoint Online REST Services in .NET | Medium

//Authentification
public GraphServiceClient GetGraphServiceClient() {
//Create a confidential client application with the provided ClientId, TenantId, and ClientSecret
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(ClientId)
.WithTenantId(TenantId)
.WithClientSecret(ClientSecret)
.Build();

//Create an authorization code provider with the confidential client application
AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication);

//Create a client credential provider with the confidential client application
ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);

//Create a GraphServiceClient and configure it with the authentication provider
return new GraphServiceClient(authenticationProvider);
}


//Retrieve profile picture by id

public static async Task<Stream> GetUsersPhotos(string id)
{
_ = _appClient ??
throw new NullReferenceException("Graph has not been initialized for app-only auth");
try
{
return await _appClient.Users[id].Photo.Content.GetAsync();
}
catch (ODataError odataError)
{
Console.WriteLine(odataError.Error.Code);
Console.WriteLine("Error Message: " + odataError.Error.Message);
return null;
}
}
//use above-mentioned functions to save profile picture to file
using (var stream = await GetUsersPhotos(user.Id))
{
using (var fileStream = new FileStream(sourceFileName, FileMode.Create, FileAccess.Write))
{
await stream.CopyToAsync(fileStream);
}
}

Conclusion

By using Microsoft Graph, we can efficiently retrieve employee profile pictures in a simple and accessible way. Now, all your applications can display coworkers' profile pictures.

Comments

View Comments